package com.leadiv.openrule;

import java.util.Arrays;
import javax.swing.DefaultListModel;

/**
 * Holds all the information needed when managing unit profiles.
 * @author pborrego
 */
public class UnitProfile {
    private int precision;
    private float resolution;
    private String name;
    private String policy;
    private boolean labels;
    private DefaultListModel levels;

    public UnitProfile() {
        this.name = "";
        this.labels = true;
        this.precision = 0;
        this.resolution = 0;
        this.policy = "";
        this.levels = new DefaultListModel();
    }

    public UnitProfile(String name, boolean labels, int precision, float resolution, String policy) {
        this.name = name;
        this.labels = labels;
        this.precision = precision;
        this.resolution = resolution;
        this.policy = policy;
        this.levels = new DefaultListModel();
        this.updateLevels();
    }

    public TickPolicy getTickPolicy() {
        return new TickPolicy(this.name, this.resolution, this.policy);
    }

    /**
     * Removes the index from the levels model.
     * @param index The position in the model to remove the level.
     */
    public void removeLevel(int index) {
        this.levels.remove(index);
        this.updatePolicy();
    }

    public void addLevel(String level) {
        int index = Arrays.binarySearch(this.levels.toArray(), level);
        if(index >= 0) return;

        this.levels.add(-(index + 1), level);
        this.updatePolicy();
    }

    private void updatePolicy() {
        int i, len;
        String[] info;
        String val;
        String newPolicy = "";

        if(0 == this.levels.size()) { this.policy = ""; return;}

        for(i=0, len=this.levels.getSize(); i<len; i++) {
            val = this.levels.getElementAt(i).toString();
            if(val.endsWith("Ticks Per Unit")) {
                newPolicy += "float/tpu|";
            }
            info = val.split(" ");
            newPolicy += info[0] + ":";
        }
        newPolicy += ";";
        newPolicy = newPolicy.replace(":;", "");
        this.policy = newPolicy;
    }

    private void updateLevels() {
        int i, len;
        String[] info;
        String[] rawlevels = policy.split(":");
        DefaultListModel dlm = new DefaultListModel();

        for(i=0, len = rawlevels.length; i<len; i++) { // for each level
            info = rawlevels[i].split("\\|");
            if(info.length == 1) {
                dlm.addElement(info[0] + " Pixel Per Tick");
                continue;
            }

            if(info[0].equals("float/tpu")) {
                dlm.addElement(info[1] + " Ticks Per Unit");
            }
        }
        this.levels = dlm;
    }

    /**
     * Determines if the string is part of the tick policy. It must be the full
     * string identifier: value + type
     * @param needle The level to find.
     * @return True if the needle is found and false if not found
     */
    public boolean isLevel(String needle) {
        int i, len;

        for(i=0, len=this.levels.getSize(); i<len; i++) {
            if(this.levels.getElementAt(i).toString().equals(needle)) {
                return true;
            }
        }

        return false;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPolicy() {
        return policy;
    }

    public void setPolicy(String policy) {
        this.policy = policy;
    }

    public int getPrecision() {
        return precision;
    }

    public void setPrecision(int precision) {
        this.precision = precision;
    }

    public float getResolution() {
        return resolution;
    }

    public void setResolution(float resolution) {
        this.resolution = resolution;
    }

    public boolean getLabels() {
        return labels;
    }

    public void setLabels(boolean labels) {
        this.labels = labels;
    }

    public DefaultListModel getLevels() {
        return levels;
    }

    public void setLevels(DefaultListModel levels) {
        this.levels = levels;
    }
}
